﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Text.RegularExpressions;
using SPAdvancedSearch;
using SPAdvancedSearch.Utility;
using SPAdvancedSearch.Editors;

namespace Tests
{
    /// <summary>
    /// Summary description for UnitTest1
    /// </summary>
    [TestClass]
    public class SPAdvancedSearchTests
    {
        public SPAdvancedSearchTests()
        {
            //
            // TODO: Add constructor logic here
            //
        }

        #region Additional test attributes
        //
        // You can use the following additional attributes as you write your tests:
        //
        // Use ClassInitialize to run code before running the first test in the class
        // [ClassInitialize()]
        // public static void MyClassInitialize(TestContext testContext) { }
        //
        // Use ClassCleanup to run code after all tests in a class have run
        // [ClassCleanup()]
        // public static void MyClassCleanup() { }
        //
        // Use TestInitialize to run code before running each test 
        // [TestInitialize()]
        // public void MyTestInitialize() { }
        //
        // Use TestCleanup to run code after each test has run
        // [TestCleanup()]
        // public void MyTestCleanup() { }
        //
        #endregion

        [TestMethod]
        public void TestRegularExpression()
        {
            string testString = "FirstName:Erik";

            MatchCollection matches = GetMatches(testString);

            Assert.IsTrue(matches.Count == 1, "There should be one match.");
            Assert.IsTrue(matches[0].Groups["Keyword"].Value == "FirstName");
            Assert.IsTrue(matches[0].Groups["Value"].Value == "Erik");

            testString = "FirstName:\"Erik\"";

            matches = GetMatches(testString);

            Assert.IsTrue(matches.Count == 1, "There should be one match.");
            Assert.IsTrue(matches[0].Groups["Keyword"].Value == "FirstName");
            Assert.IsTrue(matches[0].Groups["Value"].Value == "\"Erik\"");

            testString = "FirstName:\"Erik\" LastName:Mau";

            matches = GetMatches(testString);

            Assert.IsTrue(matches.Count == 2, "There should be two matches.");
            Assert.IsTrue(matches[0].Groups["Keyword"].Value == "FirstName");
            Assert.IsTrue(matches[0].Groups["Value"].Value == "\"Erik\"");
            Assert.IsTrue(matches[1].Groups["Keyword"].Value == "LastName");
            Assert.IsTrue(matches[1].Groups["Value"].Value == "Mau");

            testString = "FirstName:\"Erik Mau\" LastName:Mau";

            matches = GetMatches(testString);

            Assert.IsTrue(matches.Count == 2, "There should be two matches.");
            Assert.IsTrue(matches[0].Groups["Keyword"].Value == "FirstName");
            Assert.IsTrue(matches[0].Groups["Value"].Value == "\"Erik Mau\"");
            Assert.IsTrue(matches[1].Groups["Keyword"].Value == "LastName");
            Assert.IsTrue(matches[1].Groups["Value"].Value == "Mau");

            testString = "FirstName:\"Erik Mau\" LastName:\"Mau\"";

            matches = GetMatches(testString);

            Assert.IsTrue(matches.Count == 2, "There should be two matches.");
            Assert.IsTrue(matches[0].Groups["Keyword"].Value == "FirstName");
            Assert.IsTrue(matches[0].Groups["Value"].Value == "\"Erik Mau\"");
            Assert.IsTrue(matches[1].Groups["Keyword"].Value == "LastName");
            Assert.IsTrue(matches[1].Groups["Value"].Value == "\"Mau\"");


        }

        private MatchCollection GetMatches(string keywords)
        {

            Regex reg = new Regex("(?<Keyword>\\w+):(?<Value>\\w+|\"[^\"\\r\\n]*\")\\s*");
            return reg.Matches(keywords);   
        }

        [TestMethod()]
        public void TestSerialization()
        {
            List<SearchProperty> properties = new List<SearchProperty>();

            SearchProperty p = new SearchProperty();
            p.FriendlyName = "Last Name";
            p.ManagedPropertyName = "LastName";
            p.SearchValueType = SearchPropertyValueType.TextBox;

            properties.Add(p);

            p = new SearchProperty();
            p.FriendlyName = "First Name";
            p.ManagedPropertyName = "FirstName";
            p.SearchValueType = SearchPropertyValueType.TextBox;

            properties.Add(p);

            p = new SearchProperty();
            p.FriendlyName = "Category";
            p.ManagedPropertyName = "Category";
            p.SearchValueType = SearchPropertyValueType.Choice;

            ChoiceEditorControl choiceEditor = p.GetValueControl().GetEditorControl() as ChoiceEditorControl;
            choiceEditor.AddChoice("MN");
            choiceEditor.AddChoice("WI");
            choiceEditor.AddChoice("IA");
            
            properties.Add(p);

            string xml = SerializationManager.DehydrateObject(properties);

            Assert.IsTrue(xml.Length > 0, "The xml properties should be serialized.");

            List<SearchProperty> hydratedProperties = (List<SearchProperty>)SerializationManager.HydrateObjectFromXml(typeof(List<SearchProperty>), xml);

            Assert.IsTrue(hydratedProperties.Count == 3, "There should be 3 properties in the list.");

            p = hydratedProperties[2];
            Assert.IsTrue(p.SearchValueType == SearchPropertyValueType.Choice, "The 3rd property should be a Choice value type.");

            choiceEditor = p.GetValueControl().GetEditorControl() as ChoiceEditorControl;
            Assert.IsTrue(choiceEditor.Choices.Count == 3, "The number of choices should be 3.");
            Assert.IsTrue(choiceEditor.Choices[0] == "MN", "The first choice should be MN.");
            Assert.IsTrue(choiceEditor.Choices[1] == "WI", "The first choice should be WI.");
            Assert.IsTrue(choiceEditor.Choices[2] == "IA", "The first choice should be IA.");


        }
    }
}
